<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');

$ATTRS = array();

class Modelicious {
	public $table_name;
	public $class_name;
	public $version_col = 'model_version';
	public $version_id  = 0;
	public $CI;
	
	/*
	* Anything with the first letter capitalized should be interpreted to be a model name,
	* e.g. User, Bricabox
	*/
	public function __call($m, $a)
	{
		if (preg_match('/^[A-Z].*/', $m))
		{
			$_table_name = strtolower(Inflect::pluralize($m));
			$klass 		 = new Modelicious();
			return $klass->load_model($m, $_table_name);
		}
	}
	
	/*
	* Instance methods
	*/
	public function load_model($class_name, $table_name)
	{
		$this->class_name = $class_name;
		$this->table_name = $table_name;
		
		$this->CI =& get_instance();
		
		$this->_load_attrs();
		
		log_message('debug', "Modelicious: say hello to {$class_name} using '{$table_name}' table");
		
		return $this;
	}
	
	public function find_by_id($id)
	{
		return $this->find_by('id', intval($id));
	}
	
	public function find_by($field, $value)
	{
		global $BBX;
		
		$has_memcached = ($BBX['memcache'] === false) ? false : true;
		
		// 1. get the version number and id
		$query = $this->CI->db->query("SELECT id,UNIX_TIMESTAMP({$this->version_col}) as modelicious_version FROM {$this->table_name} WHERE {$field} = ? LIMIT 1", array($value));
		if ($query->num_rows() == 1)
		{
			$this->version_id = $query->first_row()->modelicious_version;
			$this->id		  = $query->first_row()->id;
			
			$mc_key = strtolower($this->class_name)."_{$this->id}_{$this->version_id}";
			
			log_message('debug', "Modelicious: looking for {$this->class_name} at {$this->id} with key {$mc_key}");
			
			// 2. does this exist in memcache?
			$_mc_ver = false;
			if ($has_memcached)
				$_mc_ver = $BBX['memcache']->get($mc_key);
			if ($_mc_ver !== false)
			{
				// found it!
				log_message('debug', "Modelicious: loading {$mc_key} from memcache");
				$_rec = $_mc_ver;
			}
			else
			{
				// nope, so get the rest of the data, save it, and continue
				log_message('debug', "Modelicious: {$mc_key} doesn't exist; loading");
				$query = $this->CI->db->query("SELECT * FROM {$this->table_name} WHERE id = ? LIMIT 1", array($this->id));
				if ($query->num_rows())
				{
					$_rec = $query->first_row();
					
					// save to memcached
					log_message('debug', "Modelicious: saving {$mc_key} to memcache");
					$BBX['memcache']->set($mc_key, $_rec, MEMCACHE_COMPRESSED, 30*60); // 30 min TTL
				}
			}
			$this->_assign_attrs($_rec);
			return $this;
		}
		else // record not found
		{
			show_error("Record not found with id {$id}");
			exit();
		}
	}
	
	/***/
	
	private function _assign_attrs($data)
	{
		global $ATTRS;
		if (isset($ATTRS[$this->class_name]))
		{
			foreach ($ATTRS[$this->class_name] as $name => $field_data)
			{
				$this->$name = $data->$name;
			}
		}
	}
	
	private function _load_attrs()
	{
		global $ATTRS;
		if (isset($ATTRS[$this->class_name]))
		{
			log_message('debug', "Modelicious: loading cached fields for {$this->class_name}");
			$_attrs = $ATTRS[$this->class_name];
		}
		else
		{
			$query = $this->CI->db->query('SHOW FIELDS FROM `'.$this->table_name.'`');
			if ($query->num_rows())
			{
				foreach ($query->result() as $field)
					$ATTRS[$this->class_name][$field->Field] = $field;
			}
			else
			{
				show_error("No fields found in table {$this->table_name}");
			}
		}
	}
}

?>